package com.aeasycredit.test;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

public class TxtHelper {

	public static void main(String[] args) throws IOException {
		
		String[] extensions = new String[] {"txt", "md"};
		Collection<File> fileList = FileUtils.listFiles(new File("D:\\"), extensions, false);
		for (File file : fileList) {
			transformFile(file);
		}

	}
	
	public static void transformFile(File file) throws IOException {
		
		System.out.println("sourceFile:" + file.getName());
		List<String> lines = FileUtils.readLines(file, "UTF-8");
		StringBuilder result = new StringBuilder();
		result.append("<html>  \r\n");
		
		String headHtml = buildHead();
		result.append(headHtml);
		result.append("<body style='font-size: 12px;font-family: Arial, Helvetica, sans-serif;'>  \r\n");
		
		long count = 0;
		boolean isCodeBlock = false; 
		boolean isUnOrderedListBlock = false; 
		boolean isTableBlock = false; 
		int tableRowCount = 0;
		for (String line : lines) {
			count ++;
			if (count == 1 && line.length() > 1 && line.codePointAt(0) == 65279) {
				line = line.substring(1);
			}
			System.out.println("line:[" + line + "] length:" + line.length());
			
			if (isUnOrderedListBlock) {
				boolean isUnOrderedList = isUnOrderedList(line);
				if (!isUnOrderedList && isUnOrderedListBlock) {
					result.append("</ul>");
					isUnOrderedListBlock = false;
				}
			}
			
			if (StringUtils.isBlank(line)) {
				result.append("<br/>\r\n");
			} else if (isTitle(line)) {
				String title = buildTitle(line);
				result.append(title);
			} else if (isCodeStart(line)) {
				String codeLanguage = line.substring(3);
				String codePrefix = String.format("<pre><code class='%s'>", codeLanguage);
				result.append(codePrefix).append("\r\n");
				isCodeBlock = true;
			} else if (isCodeEnd(line)) {
				result.append("</code></pre>\r\n");
				isCodeBlock = false;
			} else if (isLink(line)) {
				String linkHtml = buildLink(line);
				result.append(linkHtml);
			} else if (isDivide(line)) {
				result.append("<hr/>");
			} else if (isTableStart(line)) {
				result.append("<table class='table'>\r\n");
				isTableBlock = true;
			} else if (isTableEnd(line)) {
				result.append("</table>\r\n");
				isTableBlock = false;
				tableRowCount = 0;
			} else {
				
				if (isTableBlock) {
					tableRowCount ++;
					String tableRow = buildTableRow(line, tableRowCount);
					result.append(tableRow);
					continue;
				}
				
				boolean isUnOrderedList = isUnOrderedList(line);
				if (isUnOrderedList && !isUnOrderedListBlock) {
					result.append("<ul>\r\n");
					line = line.replaceFirst("^[-+*] ", "");
					line = String.format("  <li>%s</li>\r\n", line);
					result.append(line);
					isUnOrderedListBlock = true;
				} else if (!isUnOrderedList && isUnOrderedListBlock) {
					result.append("</ul>\r\n");
					isUnOrderedListBlock = false;
				} else if (isUnOrderedList && isUnOrderedListBlock) {
					line = line.replaceFirst("^[-+*] ", "");
					line = String.format("  <li>%s</li>\r\n", line);
					result.append(line);
				} else {
				
					if (isCodeBlock) {
						result.append(line + "\r\n");
					} else {
						result.append("<pre>" +line + "</pre>\r\n");	
					}
				}
			}
		}
		result.append("</body>");
		result.append("</html>");
		
		String fileNameOnSuffix = StringUtils.substringBeforeLast(file.getName(), ".");
		String targetFile = file.getParent() + fileNameOnSuffix + ".html";
		System.out.println("targetFile:" + targetFile);
		FileUtils.writeStringToFile(new File(targetFile), result.toString(), "UTF-8");
	}

	
	public static String buildHead() {
		StringBuilder result = new StringBuilder();
		result.append("<head>  \r\n");
		result.append("  <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/styles/default.min.css\"> \r\n");
		result.append("  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.2/highlight.min.js\"></script> \r\n");
		result.append("  <script>hljs.initHighlightingOnLoad();</script>  \r\n");
		result.append("  <style> \r\n");
		result.append("  table {border: 1px solid #dfdfdf;border-collapse: collapse;word-break: break-word;}  \r\n");
		result.append("  table td {border: 1px solid #c0c0c0; border-collapse: collapse; padding: 8px 14px;min-width: 50px;}  \r\n");
		result.append("  table thead th {vertical-align: middle; text-align: center; font-weight: 700;padding: 8px;border: 1px solid #ddd;line-height: 20px;}  \r\n");
		result.append("  </style>  \r\n");
		result.append("</head>  \r\n");
		return result.toString();
	}

	public static boolean isTitle(String line) {
		return line.matches("(^([0-9]+\\.)+.*)|(^#+ .*)");
	}
	
	public static boolean isCodeStart(String line) {
		return line.matches("^```[a-zA-z]+");
	}
	
	public static boolean isCodeEnd(String line) {
		return line.matches("^```");
	}
	
	public static boolean isLink(String line) {
		return line.matches(".*?(\\[.+\\]\\(.+\\).*)+");
	}
	
	public static boolean isDivide(String line) {
		return line.matches("(^[-]{3,})|(^[*]{3,})");
	}
	
	public static boolean isUnOrderedList(String line) {
		return line.matches("^[-+*] .*");
	}
	
	public static boolean isTableStart(String line) {
		return line.matches("^#-+.*");
	}
	
	public static boolean isTableEnd(String line) {
		return line.matches(".*-#$");
	}
	
	public static String buildTitle(String line) {
		int titleLevel = 0;
		if (line.matches("(^([0-9]+\\.){4}[0-9]+.*)|(^##### .*)")) {
			titleLevel = 5;
		} else if (line.matches("(^([0-9]+\\.){3}[0-9]+.*)|(^#### .*)")) {
			titleLevel = 4;
		} else if (line.matches("(^([0-9]+\\.){2}[0-9]+.*)|(^### .*)")) {
			titleLevel = 3;
		} else if (line.matches("(^([0-9]+\\.){1}[0-9]+.*)|(^## .*)")) {
			titleLevel = 2;
		} else if (line.matches("(^[0-9]+.*)|(^#.*)")) {
			titleLevel = 1;
		}
		
		line = line.replaceFirst("^#+ ", "");
		return String.format("<h%d>%s</h%d>\r\n", titleLevel, line, titleLevel);
	}
	
	public static String buildLink(String line) {
		String tempLine = line;
		Pattern pattern = Pattern.compile("\\[.*?\\]\\(.*?\\)");
        Matcher matcher = pattern.matcher(line);
        while(matcher.find()) {
        	String target = matcher.group(0);
        	String text = target.substring(1, target.indexOf("]"));
        	String url = target.substring(target.indexOf("(") + 1, target.length() - 1);
        	String linkHtml = String.format("<a href='%s' target='_blank'>%s</a>", url, text);
        	tempLine = tempLine.replace(target, linkHtml);
        }
        tempLine += "<br/>\r\n";
        return tempLine;
	}
	
	public static String buildTableRow(String line, int tableRowCount) {
		String[] fields = line.split("[\t]+");
		StringBuilder rowHtml = new StringBuilder();
		if (tableRowCount == 1) {
			rowHtml.append("  <thead>\r\n");
		}
		
		rowHtml.append("  <tr>\r\n");
		for (int i = 0; i < fields.length; i++) {
			if (tableRowCount == 1) {
				rowHtml.append("      <th>").append(fields[i]).append("</th>\r\n");
			} else {
				rowHtml.append("      <td>").append(fields[i]).append("</td>\r\n");
			}
		}
		rowHtml.append("  </tr>\r\n");
		if (tableRowCount == 1) {
			rowHtml.append("  </thead>\r\n");
		}
		return rowHtml.toString();
	}
	
}
